/*->c.viewtx    */

/* Spark!   (c) D. J. Pilling,     April 1989                         */
/*                   Filing System  Interface                         */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <ctype.h>
#include <time.h>

#include "h.os"
#include "h.wimp"
#include "h.sprite"
#include "h.bbc"
#include "h.flex"

#include "h.swis"


#include "h.def"
#include "h.wos"
#include "h.timex"

#include "h.mym"

#include "h.ftp"
#include "h.batch"
#include "h.trans"


#include "h.view"



/*****************************************************************************/


char * typetosprite(int type)
{
 static char sp[16];
 os_error * errpoi;

 if(type==CODE) strcpy(sp,"Sfile_xxx");
 else
 {
  sprintf(sp,"file_%03x",type);
  errpoi=wimp_spriteop(24,sp);
  if(!errpoi)
   sprintf(sp,"Sfile_%03x",type);
  else
   strcpy(sp,"Sfile_xxx");
 }
 return(sp);
}


char * tinysp(int type)
{
 static char sp[16];
 os_error * errpoi;

 if(type==CODE) strcpy(sp,"Ssmall_xxx");
 else
 {
  sprintf(sp,"small_%03x",type);
  errpoi=wimp_spriteop(24,sp);
  if(!errpoi)
   sprintf(sp,"Ssmall_%03x",type);
  else
   strcpy(sp,"Ssmall_xxx");
 }
 return(sp);
}



void setsprites(int posn)
{
 int type;

 type=vtable[view][posn].stat.type;
 strcpy(vtable[view][posn].typs,typetosprite(type));
 strcpy(vtable[view][posn].tiny,tinysp(type));
}


void setspritesr(int posn)
{
 setsprites(posn);
 seti(viewhandle[view],vtable[view][posn].icon,0,0);
}


/*****************************************************************************/

/* we just inserted another header/file in the current file table */
/* posn      the location in the ftable to put new entry          */


void insertentry(int posn,ficon * fi,int ow)
{
 int i;

 trashicons(view);  /* there's a catch */
                    /* fi will overwrite any icon numbers - prob. for ow */

 if(!ow)
 {
  if(vobject[view]>=posn) vobject[view]++;
  vnofiles[view]++;
  setnofiles(view,vnofiles[view]);
  for(i=vnofiles[view]-2;i>=posn;i--) vtable[view][i+1]=vtable[view][i];
 }

 vtable[view][posn]=*fi;
 vtable[view][posn].selected=0;
 vtable[view][posn].icon=-1;

 setsprites(posn);
 refreshallviews();
}


/* delete an entry from the table */

void deleteentrylo(int posn,int del)
{
 int i;

 if(del || vtable[view][posn].temporary) remove(vtable[view][posn].lname);

 if(vobject[view]==posn) vobject[view]=-1;
 else
 if(vobject[view]>posn)  vobject[view]--;

 for(i=posn;i<vnofiles[view]-1;i++) vtable[view][i]=vtable[view][i+1];

 vnofiles[view]--;
}



void deleteentry(int posn,int del)
{
 trashicons(view);
 deleteentrylo(posn,del);
 setnofiles(view,vnofiles[view]);
 refreshallviews();
}



/*****************************************************************************/

void writetypest(char * string,int posn)
{
 os_regset rx;
 int i,type;

 type=vtable[view][posn].stat.type;

 if(type==CODE) strcpy(string,"Code");
 else
 {
  rx.r[0]=18;
  rx.r[2]=type;
  os_swix(OS_FSControl,&rx);
  string[0]=rx.r[2];
  string[1]=rx.r[2]>>8;
  string[2]=rx.r[2]>>16;
  string[3]=rx.r[2]>>24;
  string[4]=rx.r[3];
  string[5]=rx.r[3]>>8;
  string[6]=rx.r[3]>>16;
  string[7]=rx.r[3]>>24;
  for(i=0;i<8;i++) if(string[i]<=32) break;
  string[i]=0;
 }
}


void writetype(int window,int icon,int posn)
{
 char string[32];
 writetypest(string,posn);
 writeicon(window,icon,string);
}


void writens(char * string,int val)
{
 os_regset rx;

 rx.r[0]=val;
 rx.r[1]=(int)string;
 rx.r[2]=12;

 os_swix(OS_ConvertFixedFileSize,&rx);
}



/* contents of text field */

/*  0..12 type        */
/* 12..16 size 1234K  */
/* 17 space           */
/* 18..23 status      */
/* 24 space           */
/* 25..43 open time   */
/* 44 space           */
/* 45..51 protocol    */
/* 52 space           */
/* 53..61 txtime      */


void writetextdata(int posn)
{
 int    txtime;
 char * text=vtable[view][posn].text;
 int    i;

 for(i=0;i<64;i++) text[i]=0;

 writens(text+12,vtable[view][posn].stat.length);
 text[16]=text[17];
 text[17]=0;

 writetypest(text,posn);

 strcpy(text+18,transtoken(ftpstatus[vtable[view][posn].state]));

 writetimedate(text+25,&vtable[view][posn].otime);

 strcpy(text+45,transtoken(ftpshortname[vtable[view][posn].protocol]));

 txtime=difftimes(&vtable[view][posn].ctime,&vtable[view][posn].otime);
 writehms(text+53,txtime);

 vtable[view][posn].text[63]=0;
}



int dynamview(void)
{
 int n;
 int posn;
 int i;
 int sulen;
 int handle;


 n=selected(&posn);

 if(n==1)    /* single file stuff */
 {
  handle=createwindow(FINFO);

  writeicon(handle,3,leaf(vtable[view][posn].lname));
  writeicon(handle,6,vtable[view][posn].typs+1);
  writetype(handle,1,posn);

  writeiconf(handle,7,"%d",(int)vtable[view][posn].stat.length);

  writefiletime(iconaddr(handle,4),&vtable[view][posn].stat);
  writetimedate(iconaddr(handle,10),&vtable[view][posn].otime);
  writetimedate(iconaddr(handle,20),&vtable[view][posn].ctime);

  writeicon(handle,15,transtoken(ftpstatus[vtable[view][posn].state]));
  writeicon(handle,16,transtoken(ftpshortname[vtable[view][posn].protocol]));

  writeicon(handle,17,vtable[view][posn].sys);
  writeicon(handle,18,vtable[view][posn].info);
 }
 else        /* selection stuff */
 {
  handle=createwindow(SELINFO);

  n=0;
  sulen=0;

  for(i=0;i<vnofiles[view];i++)
  {
   if(vtable[view][i].selected)
   {
    n++;
    sulen+=(int)vtable[view][i].stat.length;
   }
  }

  writeiconf(handle,2,"%d",sulen);
  writeiconf(handle,3,"%d",n);
 }

 return(handle);
}




int dynamviewnames(void)
{
 int handle;
 int posn;

 modbatch(0);  /* force names to be saved on terminate */

 handle=createwindow(NINFO);

 selected(&posn);

 setindirect(handle,3,sizeof(vtable[view][posn].rname)-1,
                                              vtable[view][posn].rname);
 setindirect(handle,2,sizeof(vtable[view][posn].lname)-1,
                                              vtable[view][posn].lname);
 return(handle);
}




void setpopview(void)
{
 char string[256];
 int  i;
 int  n;

 for(i=0;i<7;i++) untick(disp_menu,i);
 tick(disp_menu,viewdisp[view]);
 tick(disp_menu,viewsort[view]+3);

 n=getinfo(string);

 strcpy(menuaddr(view_menu,1),string);

/* for(i=strlen(string);i<18;i++)
 *(menuaddr(view_menu,1)+i)=32; */

 unshadest(view_menu,1,n);

 unshadest(action_menu,1,n);
 unshadest(action_menu,2,n);

 unshadest(action_menu,3,n && view==TXBFILE);
 unshadest(action_menu,4,n && view==TXBFILE);

 unshadest(action_menu,5,n==1);
}



#define SPLITS 6

static int splits[SPLITS]=
{
 0,
 12,
 18,
 25,
 45,
 53
};



static void viewredrawsub(wimp_redrawstr * redrawstr,int more)
{
 int oy;
 int ox;
 int ylo;
 int yhi;
 int n;
 int y;
 int x;
 int i;

 wimpfontstart();

 while(more)
 {
  if(viewdisp[view]==2)
  {
   ox=redrawstr->box.x0-redrawstr->scx;
   oy=redrawstr->box.y1-redrawstr->scy;

   ylo=(redrawstr->g.y1-oy);            /* small number, top of window */
   yhi=(redrawstr->g.y0-oy);            /* bigger, bottom of window */


   for(n=0;n<vnofiles[view];n++)
   {
    x=vtable[view][n].x+WIDTH;
    y=vtable[view][n].y+HEIGHT-VMARGIN;

    if(y<=(ylo+HEIGHT) && y>=yhi)
    {
     for(i=0;i<SPLITS;i++)
     {
      stringat(ox+x+splits[i]*wimpavfontwidth,oy+y,
           vtable[view][n].text+splits[i],(1<<8)|7,HEIGHT-2*VMARGIN);
     }
    }
   } 
  }
  wimp_get_rectangle(redrawstr,&more);
 }

 wimpfontend();
}




void viewredraw(void)
{
 wimp_redrawstr redrawstr;
 int            more;

 redrawstr.w=ewindow;
 wimp_redraw_wind(&redrawstr,&more);
 viewredrawsub(&redrawstr,more);
}



void viewupdatetexticon(int posn)
{
 wimp_redrawstr r;
 int            handle;

 writetextdata(posn);
 if(viewdisp[view]==2)
 {
  handle=viewhandle[view];
  if(handle)
  {
   getw(handle);
   r.box.x0=vtable[view][posn].x+WIDTH+x0;
   r.box.y0=vtable[view][posn].y+VMARGIN+y1;
   r.box.x1=vtable[view][posn].x+WIDTH+TEXTW+x0;
   r.box.y1=vtable[view][posn].y+HEIGHT-VMARGIN+y1;
   r.w=-1;
   wimp_force_redraw(&r);
  }
 }
}





static void viewsetstate(int state)
{
 int i;

 for(i=0;i<vnofiles[view];i++)
 {
  if(vtable[view][i].selected)
  {
   vtable[view][i].state=state;
   viewupdatetexticon(i);
  }
 }
}



static void viewremove(int del)
{
 int i;

 trashicons(view);

 for(i=0;i<vnofiles[view];i++)
   if(vtable[view][i].selected) deleteentrylo(i--,del);

 setnofiles(view,vnofiles[view]);
 refreshallviews();
}


static void viewsettype(void)
{
 char string[256];
 int i;
 int posn;
 fstat f;

 for(i=0;i<vnofiles[view];i++)
 {
  if(vtable[view][i].selected)
  {
   posn=i;

   sprintf(string,"settype %s %s",vtable[view][posn].lname,
                                      menuaddr(settype_menu,0));

   os_cli(string);

   f=vtable[view][posn].stat;
   stat(vtable[view][posn].lname,&f);
   if(f.object==1) vtable[view][posn].stat=f;

   setsprites(posn);
   seti(viewhandle[view],vtable[view][posn].icon,0,0);
   viewupdatetexticon(posn);
  }
 }
}



void decodeselection(int m2)
{
 switch(m2)
 {
  case 1:                        /* set type */
         viewsettype();
         break;

  case 2:                        /* remove */
         viewremove(0);
         break;

  case 3:                        /* set sent */
         viewsetstate(PSENT);
         break;

  case 4:                        /* set ready */
         viewsetstate(PREADY);
         break;

 default:
         return;
 }
 modbatch(1);
}




void decodeview(int m1,int m2,int m3)
{
 switch(m1)
 {
  case 0:
         switch(m2)       /* display */
         {
          case 0:
          case 1:
          case 2:
                 viewdisp[view]=display=m2;
                 refreshview(1);
                 break;
          case 3:
          case 4:
          case 5:
          case 6:
                 viewsort[view]=sort=m2-3;
                 refreshview(0);
                 break;
          }
          break;


   case 1:                 /* selection */
          decodeselection(m2);
          break;

   case 2:                 /* select all */
          selectall();
          break;

   case 3:                 /* clear selection */
          unselectall();
          break;

   case 4:                 /* open directory */
          opendir();
          break;
 }

 setpopview();
 m3=0;
}


void popview(void)
{
 selectone();
 setpopview();
 popmenu(view_menu);
}


